﻿using ApiManage.Applications.Mongo.Sys;
using ApiManage.Models.RequestModels;
using ApiManage.Svc.Filter;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using Rhonin.Common.Entity.Api;
using Rhonin.Common.Entity.Exception;
using Rhonin.Common.Entity.Page;
using Rhonin.Common.Extentions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ApiManage.Models.MongoMappings.Sys;
using ApiManage.Service.Mongo.Sys;

namespace ApiManage.Svc.Controllers.System
{
    /// <summary>
    /// 角色控制器
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class SysRoleController : BaseController
    {
        private readonly ISysMenuQueryService _sysMenuQueryService;
        private readonly ISysButtonQueryService _sysButtonQueryService;
        private readonly ISysColumnQueryService _sysColumnQueryService;
        private readonly ISysRoleService _sysRoleService;
        private readonly ISysRoleQueryService _sysRoleQueryService;
        /// <summary>
        /// 
        /// </summary>
        public SysRoleController(ISysMenuQueryService sysMenuQueryService,
            ISysButtonQueryService sysButtonQueryService,
            ISysColumnQueryService sysColumnQueryService,
            ISysRoleService sysRoleService,
            ISysRoleQueryService sysRoleQueryService)
        {
            _sysMenuQueryService = sysMenuQueryService;
            _sysColumnQueryService = sysColumnQueryService;
            _sysButtonQueryService = sysButtonQueryService;
            _sysRoleService = sysRoleService;
            _sysRoleQueryService = sysRoleQueryService;
        }
        /// <summary>
        /// 分页获取角色
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [Route("GetPage"), HttpGet, CheckLogin]
        public ApiResult<PageResult<SysRole>> GetPage(string name, int pageIndex, int pageSize)
        {
            var param = new QueryPage
            {
                PageIndex = pageIndex,
                PageSize = pageSize
            };
            Expression<Func<SysRole, bool>> where = o => o.Mark != 9;
            where = where.AndIf(o => o.RoleName.Equals(name) || o.RoleName.Equals(name), !string.IsNullOrEmpty(name));
            var list = _sysRoleQueryService.GetList(where);
            var result = new PageResult<SysRole>()
            {
                TotalCount = list.Count,
                Items = list.OrderByDescending(o => o.CreateTime).Skip(param.Skip).Take(param.Limit),
                PageParameter = param
            };
            return CreateResult(result);
        }
        /// <summary>
        /// 编辑角色
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("Save"), HttpPost, CheckLogin]
        public ApiResult Save(SysRoleExtend param)
        {
            if (string.IsNullOrEmpty(param.RoleName))
                throw new ApiException("角色名称不能为空");
            if (string.IsNullOrEmpty(param.Id))
            {
                _sysRoleService.Insert(new SysRole
                {
                    RoleName = param.RoleName,
                    RoleMenuIds = param.RoleMenuIds,
                    RoleButtonIds = param.RoleButtonIds,
                    RoleColumnIds = param.RoleColumnIds,
                    Mark = param.Mark
                });
            }
            else
            {
                _sysRoleService.Update(o => o.Id == new ObjectId(param.Id), Builders<SysRole>.Update
                    .Set("RoleName", param.RoleName)
                    .Set("RoleMenuIds", param.RoleMenuIds)
                    .Set("RoleButtonIds", param.RoleButtonIds)
                    .Set("RoleColumnIds", param.RoleColumnIds)
                    .Set("Mark", param.Mark));
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("Remove"), HttpPost, CheckLogin]
        public ApiResult Remove(IdParam param)
        {
            try
            {
                _sysRoleService.Delete(r => r.Id == new ObjectId(param.Id));
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 获取菜单及其权限
        /// </summary>
        /// <returns></returns>
        [Route("GetAllMenuAndButton"), HttpGet, CheckLogin]
        public ApiResult<List<SysMenu>> GetAllMenuAndButton()
        {
            Expression<Func<SysMenu, bool>> where = o => o.Mark != 9;
            var allMenus = _sysMenuQueryService.GetList(where);
            var topMenu = allMenus.Where(o => o.MenuUp.IsNullOrEmpty()).OrderBy(o => o.Sort).ToList();
            foreach (var item in topMenu)
            {
                item.KeyStr = "menu_" + item.Id;
                GetChildren(item, allMenus);
            }
            return CreateResult(topMenu);
        }
        private void GetChildren(SysMenu menu, List<SysMenu> allMenu)
        {
            var childrenMenu = allMenu.Where(o => o.MenuUp == menu.Id.ToString()).OrderBy(o => o.Sort).ToList();
            var children = new List<SysMenu>();
            if (childrenMenu.Count <= 0)
            {
                var button = _sysButtonQueryService.GetList(o => o.MenuId == menu.Id.ToString() && o.Mark == 1).OrderBy(o => o.Sort).ToList();
                var column = _sysColumnQueryService.GetList(o => o.MenuId == menu.Id.ToString() && o.Mark == 1).OrderBy(o => o.Sort).ToList();
                if (button.Count > 0)
                {
                    children.Add(new SysMenu
                    {
                        MenuId = -1,
                        MenuUp = menu.Id.ToString(),
                        MenuName = "按钮",
                        KeyStr = "button_" + menu.Id + "_button",
                        Children = button.Select(o => new SysMenu
                        {
                            Id = o.Id,
                            MenuUp = (-1).ToString(),
                            MenuName = o.FullName,
                            KeyStr = "button_" + o.Id
                        }).ToList()
                    });
                }
                if (column.Count > 0)
                {
                    children.Add(new SysMenu()
                    {
                        MenuId = -2,
                        MenuUp = menu.Id.ToString(),
                        MenuName = "列",
                        KeyStr = "column_" + menu.Id + "_column",
                        Children = column.Select(o => new SysMenu
                        {
                            Id = o.Id,
                            MenuUp = (-1).ToString(),
                            MenuName = o.FullName,
                            KeyStr = "column_" + o.Id
                        }).ToList()
                    });
                }
                menu.Children = children;
            }
            else
            {
                foreach (var item in childrenMenu)
                {
                    item.KeyStr = "menu_" + item.Id;
                    GetChildren(item, allMenu);
                }
                menu.Children = childrenMenu;
            }
        }
    }
}